@page "/account/login"
@page "/account/login/{returnurl}"

@using BlazorBoilerplate.Shared.Dto.Account

@layout LoginLayout
@inject NavigationManager navigationManager
@inject AuthenticationStateProvider authStateProvider
@inject IMatToaster matToaster
@inject AppState appState
@inject NavigationManager NavigationManager
@inject IJSRuntime js

@using static Microsoft.AspNetCore.Http.StatusCodes

<MatCard>
    <div class="hidden-mdc-down">
        <MatIconButton Icon="exit_to_app" Class="float-left" @onclick="GoBack" />
        <MatIconButton Icon="home" Class="float-left" Link="/" />
    </div>

    <div class="logo">
        <a href="/" title="Blazor Boilerplate Home"><img src="_content/BlazorBoilerplate.CommonUI/images/blazorboilerplate.svg" style="width:100px;" title="Blazor Boilerplate Home" alt="Blazor Boilerplate" /><br />Blazor Boilerplate</a>
        <br />
        <h4>Log In</h4>
        User -> Username: <b>user</b> Password: <b>user123</b><br />
        Admin -> Username: <b>admin</b> Password: <b>admin123</b><br />
    </div>
    <EditForm Model="@loginParameters" OnValidSubmit="@SubmitLogin">
        <DataAnnotationsValidator />
        <ValidationSummary />
        <fieldset>
            <div class="form-group">
                <MatTextField id="userName" @bind-Value="@loginParameters.UserName" Label="User Name" Icon="person" IconTrailing="true" FullWidth="true" Required="true" tabindex="1"></MatTextField>
            </div>
            <div class="form-group">
                <MatTextField @bind-Value="@loginParameters.Password" Label="Password" Icon="lock_outline" IconTrailing="true" FullWidth="true" Required="true" Type="password" tabindex="2"></MatTextField>
            </div>
            <div class="form-group">
                <MatButton class="float-right" Type="submit" Raised="true" tabindex="3">Login</MatButton>
                <MatCheckbox @bind-Value="@loginParameters.RememberMe" class="filled-in chk-col-blue">Remember Me</MatCheckbox>
            </div>
            <hr />
            <div>
                <MatButton class="float-left" OnClick="@Register" Raised="true">Create account</MatButton>
                <MatButton class="float-right" OnClick="@GoogleSignIn" Raised="true">Sign in with <img height="18" style="margin-left: 5px" src="https://www.google.pl/images/branding/googlelogo/2x/googlelogo_color_92x30dp.png" /></MatButton><br />
            </div>
        </fieldset>
    </EditForm>
</MatCard>
<MatAccordion>
    <MatExpansionPanel @bind-Expanded="@forgotPasswordToggle">
        <MatExpansionPanelSummary>
            <MatExpansionPanelHeader>Forgot Password?</MatExpansionPanelHeader>
            <MatExpansionPanelSubHeader></MatExpansionPanelSubHeader>
        </MatExpansionPanelSummary>
        <MatExpansionPanelDetails>
            <EditForm Model="@forgotPasswordParameters" OnValidSubmit="@ForgotPassword">
                <DataAnnotationsValidator />
                <ValidationSummary />

                <div class="form-group">
                    <MatTextField @bind-Value="@forgotPasswordParameters.Email" Label="Email" Icon="mail_outline" IconTrailing="true" FullWidth="true" Required="true"></MatTextField>
                </div>
                <div class="form-group">
                    <MatButton class="float-right" Type="submit" Raised="true">Submit</MatButton>
                </div>
            </EditForm>
        </MatExpansionPanelDetails>
    </MatExpansionPanel>
</MatAccordion>

@code {

    string navigateTo = "";
    bool forgotPasswordToggle = false;
    LoginDto loginParameters { get; set; } = new LoginDto();
    ForgotPasswordDto forgotPasswordParameters { get; set; } = new ForgotPasswordDto();

    [Parameter]
    public string ReturnUrl { get; set; }

    private void GoBack()
    {
        if (string.IsNullOrEmpty(ReturnUrl))
            ReturnUrl = "";
        NavigationManager.NavigateTo(ReturnUrl, forceLoad: false);
    }

    [CascadingParameter]
    Task<AuthenticationState> authenticationStateTask { get; set; }

    protected override async Task OnParametersSetAsync()
    {
        var user = (await authenticationStateTask).User;

        if (user.Identity.IsAuthenticated)
        {
            navigationManager.NavigateTo(navigationManager.BaseUri + navigateTo, forceLoad: true);
        }
    }

    protected override async Task OnAfterRenderAsync(bool firstRender)
    {
        if (firstRender)
            await js.InvokeVoidAsync("SetFocus", "userName");

        await base.OnAfterRenderAsync(firstRender);
    }

    void GoogleSignIn()
    {
        navigationManager.NavigateTo(navigationManager.BaseUri + "api/externalauth/challenge/google", true);
    }

    void Register()
    {
        navigationManager.NavigateTo("/account/register");
    }

    async Task SubmitLogin()
    {
        try
        {
            var response = await ((IdentityAuthenticationStateProvider)authStateProvider).Login(loginParameters);
            if (response.StatusCode == Status200OK)
            {
                // On successful Login the response.Message is the Last Page Visited from User Profile
                // We can't navigate yet as the setup is proceeding asynchronously
                if (!string.IsNullOrEmpty(response.Message))
                {
                    navigateTo = response.Message;
                }
                else
                {
                    navigateTo = "/dashboard";
                }
            }
            else
            {
                matToaster.Add(response.Message, MatToastType.Danger, "Login Attempt Failed");
            }
        }
        catch (Exception ex)
        {
            matToaster.Add(ex.Message, MatToastType.Danger, "Login Attempt Failed");
        }
    }

    async Task ForgotPassword()
    {
        try
        {
            await ((IdentityAuthenticationStateProvider)authStateProvider).ForgotPassword(forgotPasswordParameters);
            matToaster.Add("Forgot Password Email Sent", MatToastType.Success);
            forgotPasswordParameters.Email = "";
            forgotPasswordToggle = false;
        }
        catch (Exception ex)
        {
            matToaster.Add(ex.Message, MatToastType.Danger, "Reset Password Attempt Failed");
        }
    }
}